#include"TaskQueue.hpp"

namespace  tp{

TaskQueue::TaskQueue(size_t queSize)
:_taskque()
,_queSize(queSize)
,_mutex()
,_notEmpty(_mutex)
,_notFull(_mutex)
,_flag(true)
{

}

TaskQueue::~TaskQueue(){

}
    
bool TaskQueue::empty() const{
    return 0 == _taskque.size();
}
    
bool TaskQueue::full() const{
    return _queSize == _taskque.size();
}

void TaskQueue::push(ElemType && elem){
    MutexAutoRelease ar(_mutex);
    /* _mutex.lock(); */

    while(full()){
        _notFull.wait();
    }
    _taskque.push(std::move(elem));
    _notEmpty.notify();

    /* _mutex.unlock(); */
}
    
ElemType TaskQueue::pop(){
    MutexAutoRelease ar(_mutex);
    /* _mutex.lock(); */

    while(empty() && _flag){
        _notEmpty.wait();
    }

    if(_flag){
        ElemType tmp = _taskque.front();
        _taskque.pop();

        _notFull.notify();
        /* _mutex.unlock(); */
        return tmp;
    }else{
        /* _mutex.unlock(); */
        return nullptr;
    }
}

void TaskQueue::wakeup(){
    _flag = false;
    _notEmpty.notifyAll();
}

}//end of namespace tp
